
#include "base_predictor.h"
#include "common/base_struct.h"

namespace ai {

int BasePredictor::stop() {
  int try_cnt = 200;
  if (stop_flag == common::CameraGrabing) {
    stop_flag = common::CameraOpened;
    while (stop_flag != common::CameraClosed && try_cnt-- > 0) {
      spdlog::get("logger")->info("BasePredictor::stop stop_flag: {} ", stop_flag);
      std::this_thread::sleep_for(milliseconds(50));
    }
    if (try_cnt < 0) {
      spdlog::get("logger")->info("ERROR. BasePredictor::stop _exit.");
      _exit(0);
    }
  }
  return 0;
}

int BasePredictor::run_thread() {
  // std::thread(&RKDetPredictor::start_postprocess_thread_imp, this).detach();
  int fps_cnt = 0;
  float npu_infer_fps = 0;
  int64_t start_time = 0, end_time = 0;
  start_time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();

  stop_flag = common::CameraGrabing;
  while (stop_flag == common::CameraGrabing) {
    // std::this_thread::sleep_for(milliseconds(500));
    mng->in_data_mtx.lock();
    int idx = 0;
    for (idx = mng->in_loop_idx[mdl->model_id]; idx < mng->in_datas[mdl->model_id].size(); idx++) {
      auto& in_data = mng->in_datas[mdl->model_id][idx];
      if (in_data == nullptr) {continue;}
      // std::cout << "in_data->model_id: " << in_data->model_id << " mdl->model_id:" << mdl->model_id << std::endl;

      if (in_data->model_id != mdl->model_id) {continue;}
      // if (in_data->model_id == "cls_fire_smog_mmaction.20250303") {
      //   std::cout << "in_data->model_id: " << in_data->model_id << " mdl->model_id:" << mdl->model_id << std::endl;
      // }
      if (in_data->rec_flag != 0) {continue;}
      // if (in_data->cnt == rec_data->cnt) {continue;}
      // std::cout << "rec_data: " << in_data->img.rows << " " << in_data->img.cols << std::endl;
      *rec_data = *in_data;
      in_data->rec_flag = 1;
      mng->in_loop_idx[mdl->model_id] = idx+1;
      // std::cout << "rec_data->infer_id: " << rec_data->infer_id << std::endl;
      break;
    }
    // 循环扫描mng->in_datas一次， mng->loop_idx就要置0 
    if (idx == mng->in_datas[mdl->model_id].size()) {mng->in_loop_idx[mdl->model_id]=0;}
    mng->in_data_mtx.unlock();

    if (rec_data->infer_id < 0) {
      std::this_thread::sleep_for(std::chrono::milliseconds(3)); 
      continue;
    }

    // std::cout << "gpu_id:" << mdl->cfg->gpu_id << " mdl->model_id:" << mdl->model_id << " infer_id:" << rec_data->infer_id << " source_id:" << rec_data->source_id << std::endl;
    ai::InferResult infer_res(rec_data->source_id, rec_data->infer_id);
    RunDet(rec_data, infer_res.infer_res);
    mng->out_data_mtx.lock();
    mng->out_datas[mdl->model_id][rec_data->infer_id] = infer_res;  //将处理后的数据返回到det_infos,加入队列中
    mng->out_data_mtx.unlock();
    fps_cnt++;

    // mng->in_data_mtx.lock();
    // mng->in_datas[mdl->model_id][rec_data->infer_id]->rec_flag = 0;
    rec_data->infer_id = -1;
    // mng->in_data_mtx.unlock();

    end_time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
    if (end_time - start_time > 5 * 1e3) {
      npu_infer_fps = 1.0 / ((end_time - start_time) / (fps_cnt * 1e3));
      std::cout << "npu:"<< mdl->cfg->gpu_id << " infer_fps:" << npu_infer_fps << std::endl;
      start_time = end_time;
      fps_cnt = 0;
    }
    
  }

  stop_flag = common::CameraClosed;
  return 0;
}



}  // namespace ai
